package com.ala4.oxcafe.boot.handler;

import com.ala4.oxcafe.boot.manager.UserTokenManager;
import com.ala4.oxcafe.common.utils.JSONUtil;
import com.ala4.oxcafe.common.utils.ResponseWriter;
import com.ala4.oxcafe.constants.SecurityConstants;
import com.ala4.oxcafe.domain.R;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author PING
 * @date 2025/8/14 21:44
 */
@Slf4j
public class UserLogoutSuccessHandler implements LogoutSuccessHandler {

    private static final Pattern authorizationPattern = Pattern.compile("^Bearer (?<token>[a-zA-Z0-9-._~+/]+=*)$", Pattern.CASE_INSENSITIVE);

    private final UserTokenManager userTokenManager;

    public UserLogoutSuccessHandler(UserTokenManager userTokenManager) {
        this.userTokenManager = userTokenManager;
    }

    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        String authorization = request.getHeader(HttpHeaders.AUTHORIZATION);
        if (StringUtils.startsWithIgnoreCase(authorization, SecurityConstants.HEADER_UPP_BEARER)) {
            Matcher matcher = authorizationPattern.matcher(authorization);
            if (!matcher.matches()) {
                throw new OAuth2AuthenticationException("Bearer token is malformed");
            }
            String userToken = matcher.group("token");
            log.debug("用户登出:{}", JSONUtil.toJsonStr(authorization));
            userTokenManager.offlineUser(userToken);
        }
        ResponseWriter.write(response, R.ok());
    }
}
